package baiqitun.stupro.api.controller;

import baiqitun.stupro.api.model.UserInfo;
import baiqitun.stupro.api.service.UserInfoService;
import baiqitun.stupro.common.exception.enums.support.StuproExceptionEnum;
import baiqitun.stupro.common.exception.enums.support.NotFoundExceptionEnum;
import baiqitun.stupro.common.exception.support.NotFoundException;
import baiqitun.stupro.common.exception.StuproException;
import baiqitun.stupro.common.model.Result;
import baiqitun.stupro.common.util.AuthUtil;
import baiqitun.stupro.common.util.ResultUtil;
import baiqitun.stupro.common.util.excel.ExcelDataSaver;
import baiqitun.stupro.common.validate.group.SaveGroup;
import baiqitun.stupro.security.entity.*;
import baiqitun.stupro.security.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

/**
 * @author kedaji
 */
@Api(description = "用户控制器")
@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysDepartUserService sysDepartUserService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private SysDepartUserRoleService sysDepartUserRoleService;
    @Qualifier("studentInfoSaver")
    @Autowired
    private ExcelDataSaver studentSaver;
    @Qualifier("tutorInfoSaver")
    @Autowired
    private ExcelDataSaver tutorSaver;

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("获取当前用户的登录信息")
    @GetMapping("/info")
    public Result<UserInfo> info(Authentication authentication){
        String username = AuthUtil.getUsername(authentication);
        UserInfo info = userInfoService.getInfo(username);
        return ResultUtil.ok(info);
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("获取系统的所有管理员")
    @GetMapping("/administrator")
    public Result<?> listAdministrator(){
        List<SysUser> admins = sysUserRoleService.listAdministrator();
        List<UserInfo> adminInfos = new LinkedList<>();
        for (SysUser tmpAdmin: admins){
            UserInfo adminInfo = new UserInfo();
            adminInfo.setName(tmpAdmin.getRealName()).setUsername(adminInfo.getUsername()).setAvatar(tmpAdmin.getAvatar()).setCreateDateTime(tmpAdmin.getCreateDateTime());
            List<SysDepart> departs = sysDepartUserService.listDepartForUser(tmpAdmin.getId());
            adminInfo.setDeparts(departs);
            adminInfos.add(adminInfo);
        }

        return ResultUtil.ok(adminInfos);
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("使用id获取指定的用户基本信息")
    @GetMapping("/{id}")
    public Result<SysUser> getById(@ApiParam("部门id") @PathVariable("id") @NotBlank(message = "用户id不能为空") String id){
        SysUser user = sysUserService.getById(id);
        if (user == null){
            throw new NotFoundException(NotFoundExceptionEnum.USER_NOT_FOUND);
        }
        user.setPassword(null);
        return ResultUtil.ok(user);
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("向指定系添加一个管理员")
    @PostMapping("/administrator")
    public Result<?> saveAdministrator(Authentication authentication,
                                       @Validated(SaveGroup.class) SysUser user,
                                       @ApiParam("所在系的id") @NotBlank(message = "部门名称不能为空") String departId){
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        user.setCreateBy(userDetails.getUsername());
        sysDepartUserRoleService.saveAdministratorToRootDepart(user, departId);
        return ResultUtil.ok();
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("向指定部门批量导入学生")
    @PostMapping("/student/import")
    public Result<?> importStudentFromExcel(Authentication authentication, HttpServletRequest request,
                                            @ApiParam("部门id") @NotBlank(message = "部门id不能为空") String departId) throws IOException {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        importExcel(request, departId, userDetails.getUsername(), studentSaver);
        return ResultUtil.ok();
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("向指定部门批量导入导师")
    @PostMapping("/tutor/import")
    public Result<?> importTutorFromExcel(Authentication authentication, HttpServletRequest request,
                                          @ApiParam("部门id") @NotBlank(message = "部门id不能为空") String departId) throws IOException {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        importExcel(request, departId, userDetails.getUsername(), tutorSaver);
        return ResultUtil.ok();
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("删除指定用户信息")
    @DeleteMapping("/{id}")
    public Result<?> removeById(Authentication authentication,
                                @ApiParam("用户id") @PathVariable("id") @NotBlank String id){
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        sysUserService.removeById(id, userDetails.getUsername());
        return ResultUtil.ok();
    }

    @ResponseStatus(HttpStatus.OK)
    @ApiOperation("修改用户密码")
    @PutMapping
    public Result<?> updatePassword(Authentication authentication,
                                    @ApiParam("id") @NotBlank(message = "用户id不能为空") String id,
                                    @ApiParam("密码") @NotBlank(message = "密码不能为空") String password){
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        sysUserService.updatePassword(id, password, userDetails.getUsername());
        return ResultUtil.ok();
    }

    private void importExcel(HttpServletRequest request, String departId, String createBy, ExcelDataSaver saver) throws IOException {

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile multipartFile = multipartRequest.getFile("file");
        if (multipartFile == null){
            throw new StuproException(StuproExceptionEnum.PARAMETER_CANNOT_NULL).put("文件", null);
        }
        InputStream inputStream = multipartFile.getInputStream();
        HashMap<String, String> args = new HashMap<>();
        args.put("departId", departId);
        args.put("createBy", createBy);
        saver.save(inputStream, args);
    }
}
